import pandas as pd

'''
一、数据清洗、处理： (此步骤也可以在Excel中完成 再读入数据)
'''
datatmsp = pd.read_excel('./data/datatmsp1.xls')  # 读取爬取的数据
print('datatmsp.shape', datatmsp.shape)

# 数据缺失值分析
# 安装模块：pip install missingno
import missingno as msno

'''
模块缺失图
'''
msno.bar(datatmsp.sample(len(datatmsp)), figsize=(10, 4))

# 删除缺失值过半的列
half_count = len(datatmsp) / 2
datatmsp = datatmsp.dropna(thresh=half_count, axis=1)

# 删除重复行：
datatmsp = datatmsp.drop_duplicates()

'''
说明：根据需求，本项目中我只取了 item_loc, raw_title, view_price, view_sales 这4列数据，
主要对 标题、区域、价格、销量 进行分析，代码如下:
'''
# 取出这4列数据：
data = datatmsp[['item_loc', 'raw_title', 'view_price', 'view_sales']]
data.head()  # 默认查看前5行数据

# 对 item_loc 列的省份和城市 进行拆分 得出 province 和 city 两列

# 生成province列：
data['province'] = data.item_loc.apply(lambda x: x.split()[0])

# 注：因直辖市的省份和城市相同 这里根据字符长度进行判断：
data['city'] = data.item_loc.apply(lambda x: x.split()[0] if len(x) < 4 else x.split()[1])

# 提取 view_sales 列中的数字，得到 sales 列：
data['sales'] = data.view_sales.apply(lambda x: str(x.split('人')[0]).replace('+', ''))

# 查看各列数据类型
print(data.dtypes)

# 将数据类型进行转换
data['sales'] = data.sales.astype('int')

list_col = ['province', 'city']
for i in list_col:
    data[i] = data[i].astype('category')

# 删除不用的列：
data = data.drop(['item_loc', 'view_sales'], axis=1)

import numpy as np
import matplotlib
from matplotlib import pyplot as plt

font = {'family': 'SimHei'}  # 设置字体
matplotlib.rc('font', **font)

'''
【1】. 商品的价格分布情况分析：
'''
data_p = data[data['view_price'] < 60000]

plt.figure(figsize=(7, 5))  # 画布大小
plt.hist(data_p['view_price'], bins=10, color='purple')  # 分为10组
plt.xlabel('价格', fontsize=12)
plt.ylabel('商品数量', fontsize=12)
plt.title('不同价格对应的商品数量分布', fontsize=15)
plt.savefig('./data/价格对应的商品数量分布图.jpg', dpi=800, bbox_inches='tight')
plt.show()

'''
由图表可知：
1. 商品数量随着价格总体呈现下降阶梯形势，价格越高，在售的商品越少；
2. 低价位商品居多，价格在1000-10000之间的商品最多，10000-20000之间的次之，价格2万以上的商品较少；
3. 价格2万元以上的商品，在售商品数量差异不大。
'''

'''
【2】. 商品的销量分布情况分析：
  为了使可视化效果更加直观，这里我们选择销量大于100的商品。
'''
data_s = data[data['sales'] > 100]
print('销量100以上的商品占比: %.3f' % (len(data_s) / len(data)))

plt.figure(figsize=(7, 5))
plt.hist(data_s['sales'], bins=20, color='purple')  # 分为20组
plt.xlabel('销量', fontsize=12)
plt.ylabel('商品数量', fontsize=12)
plt.title('不同销量对应的商品数量分布', fontsize=15)
plt.savefig('./data/销量对应的商品数量分布图.jpg', dpi=800, bbox_inches='tight')
plt.show()

'''
由图表及数据可知：
1. 销量1200以上的商品仅占少数 ，其中销量200-400之间的商品最多，1000-1200之间的次之；
2. 销量400-1000之间，商品的数量随着销量呈现下降趋势，且趋势陡峭，低销量商品居多；
3. 销量1200以上的商品很少。
'''

'''
【3】. 不同价格区间的商品的平均销量分布： 见下
   代码如下：
'''
data['price'] = data.view_price.astype('int')  # 转为整型

# 用 qcut 将price列分为12组
data['group'] = pd.qcut(data.price, 12)
df_group = data.group.value_counts().reset_index()  # 生成数据框并重设索引

# 以group列进行分类求sales的均值：
df_s_g = data[['sales', 'group']].groupby('group').mean().reset_index()

# 绘柱形图：
index = np.arange(df_s_g.group.size)
plt.figure(figsize=(8, 4))
plt.bar(index, df_s_g.sales, color='purple')
plt.xticks(index, df_s_g.group, fontsize=11, rotation=30)
plt.xlabel('价格区间')
plt.ylabel('平均销量')
plt.title('不同价格区间的商品的平均销量')
plt.savefig('./data/商品的平均销量.jpg', dpi=800, bbox_inches='tight')
plt.show()

'''
由图表可知：
1. 价格在519-979之间的商品平均销量最高，979-1639之间的次之，10588元以上的最低；
2. 总体呈现递减的趋势，最高峰处于相对低价位阶段；
3. 说明广大消费者对购买笔记本电脑的需求更多处于低价位阶段，在979元以上 价位越高 平均销量基本是越少。
'''

'''
【4】. 商品价格对销量的影响分析：
   代码如下：
'''
fig, ax = plt.subplots(figsize=(8, 5))
ax.scatter(data_p['view_price'], data_p['sales'], color='purple')
ax.set_xlabel('价格')
ax.set_ylabel('销量')
ax.set_title('商品价格对销量的影响', fontsize=14)
plt.savefig('./data/商品价格对销量的影响.jpg', dpi=800, bbox_inches='tight')
plt.show()

'''
由图表可知：
1. 总体趋势：随着商品价格增多 其销量减少，商品价格对其销量影响很大；
2. 价格500-5000之间的少数商品销量冲的很高，价格5000-10000之间的商品少数相对较高，多数销量偏低，
但价格10000以上的商品销量均很低 没有销量突出的商品。
'''

'''
【5】. 商品价格对销售额的影响分析：
   代码如下：
'''
data['GMV'] = data['price'] * data['sales']

import seaborn as sns

fig = sns.regplot(x='price', y='GMV', data=data, color='purple')
fig.get_figure().savefig('./data/商品价格对销售额的影响分析.jpg', dpi=800, bbox_inches='tight')


'''
由图表可知：
1. 总体趋势：由线性回归拟合线可以看出，商品销售额随着价格增长呈现下降趋势；
2. 多数商品的价格偏低，销售额偏高；
3. 价格在0-10000的商品只有少数销售额较高，价格2万-3万的商品只有少数销售额较高，价格3-6万的商品很少销售额。
'''

'''
【6】. 不同省份的商品数量分布：
   代码如下：
'''
plt.figure(figsize=(8, 4))
data.province.value_counts().plot(kind='bar', color='purple')
plt.xticks(rotation=0)
plt.xlabel('省份')
plt.ylabel('数量')
plt.title('不同省份的商品数量分布')
plt.savefig('./data/商品数量分布.jpg', dpi=800, bbox_inches='tight')
plt.show()

'''
由图表可知：
1. 广东的最多，北京次之，上海第三，尤其是广东的数量远超过北京、上海、江苏等地，说明在笔记本电脑这个子类目，广东的店铺占主导地位；
2. 江浙沪等地的数量差异不大，基本相当。
'''

'''
【7】. 不同省份的商品平均销量分布：
   代码如下：
'''
pro_sales = data.pivot_table(index='province', values='sales', aggfunc=np.mean)  # 分类求均值
pro_sales.sort_values('sales', inplace=True, ascending=False)  # 排序
pro_sales = pro_sales.reset_index()  # 重设索引

index = np.arange(pro_sales.sales.size)
plt.figure(figsize=(8, 4))
plt.bar(index, pro_sales.sales, color='purple')
plt.xticks(index, pro_sales.province, fontsize=11, rotation=0)
plt.xlabel('province')
plt.ylabel('mean_sales')
plt.title('不同省份的商品平均销量分布')
plt.savefig('./data/商品平均销量分布.jpg', dpi=800, bbox_inches='tight')
plt.show()
'''
由图表可知：
1. 安徽的最多，浙江次之，上海第三，尤其是安徽的数量远超过浙江、湖北、广东等地，说明在笔记本销售这个子类目，安徽的店铺占主导地位；
2. 上海，湖北，广东，江苏等地的数量差异不大，基本相当。
'''

'''
【8】. 最高价，最低价，平均价：
   代码如下：
'''
price = data['view_price'].values.tolist()
max_p = max(price)
min_p = min(price)
mean = sum(price) / len(price)

index = ['最高价', '最低价', '平均价']
price1 = [max_p, min_p, mean]
plt.figure(figsize=(8, 4))
p1 = plt.bar(index, price1, color='purple')
plt.bar_label(p1, label_type='edge')
plt.savefig('./data/价格详情.jpg', dpi=800, bbox_inches='tight')
plt.show()
'''
由图表可知：
1. 笔记本电脑最高价：58999.0
2. 笔记本电脑最低价：519.0
3. 笔记本电脑平均价：5456.49
'''

'''
【9】. 商品价格百分位数： 
   代码如下：
'''
data['price'] = data.view_price.astype('int')  # 转为整型

# 用 qcut 将price列分为6组
data['group'] = pd.qcut(data.price, 6)
df_group = data.group.value_counts().reset_index()  # 生成数据框并重设索引

data1 = df_group['group'].values.tolist()
group = list(map(str, df_group['index'].values.tolist()))
colors = ['#9999ff', '#ff9999', '#7777aa', '#4825c7', '#2ac725', '#c78625']  # 自定义颜色

plt.figure(figsize=(8, 4))
# 将横、纵坐标轴标准化处理，确保饼图是一个正圆，否则为椭圆
plt.axes(aspect='equal')

plt.pie(x=[data1[0] / sum(data1), data1[1] / sum(data1), data1[2] / sum(data1), data1[3] / sum(data1),
           data1[4] / sum(data1), data1[5] / sum(data1)],  # 绘图数据
        labels=group,  # 添加教育水平标签
        colors=colors,  # 设置饼图的自定义填充色
        autopct='%.1f%%',  # 设置百分比的格式，这里保留一位小数
        pctdistance=0.8,  # 设置百分比标签与圆心的距离
        labeldistance=1.1,  # 设置教育水平标签与圆心的距离
        startangle=180,  # 设置饼图的初始角度
        radius=2,  # 设置饼图的半径
        counterclock=False,  # 是否逆时针，这里设置为顺时针方向
        wedgeprops={'linewidth': 1.5, 'edgecolor': 'red'},  # 设置饼图内外边界的属性值
        textprops={'fontsize': 8, 'color': 'black'},  # 设置文本标签的属性值
        )
plt.savefig('./data/商品价格百分位数.jpg', dpi=800, bbox_inches='tight')
plt.show()
'''
由图表可知：
1. 价格在3399-4699之间的价格百分位数最高，占17%
2. 其他价位的百分位数均在16%-17%之间
'''

